Programação funcional é um paradigma que trata a computação como uma avaliação de funções matemáticas. Tais funções podem ser aplicadas em sequências de dados (geralmente listas). São exemplos de linguagens funcionais: LISP, Scheme e Haskell (esta última influenciou o projeto do Python de forma marcante).
As operações básicas do paradigma funcional são implementadas no Python pelas funções builtin map()
, filter()
, reduce()
e zip()
.
No Python, lambda é uma função anônima composta apenas por expressões. As funções lambda podem ter apenas uma linha, e podem ser atribuídas a uma variável. Funções lambda são muito usadas em programação funcional.
Sintaxe:
lambda <lista de variáveis>: <expressões>
Exemplo:
In [1]:
# Amplitude de um vetor 3D
amp = lambda x, y, z: (x ** 2 + y ** 2 + z ** 2) ** .5
print amp(1, 1, 1)
print amp(3, 4, 5)
Funções lambda consomem menos recursos computacionais que as funções convencionais, porém são mais limitados.
O mapeamento consiste em aplicar uma função a todos os itens de uma sequência, gerando outra lista contendo os resultados e com o mesmo tamanho da lista inicial.
No Python, o mapeamento é implementado pela função map()
.
Exemplos:
In [2]:
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
# log na base 10
from math import log10
print map(log10, nums)
# Dividindo por 3
print map(lambda x: x / 3, nums)
A função map()
sempre retorna uma lista.
Na filtragem, uma função é aplicada em todos os itens de uma sequência, se a função retornar um valor que seja avaliado como verdadeiro, o item original fará parte da sequência resultante.
No Python, a filtragem é implementada pela função filter()
.
Exemplo:
In [3]:
# Selecionando apenas os ímpares
print filter(lambda x: x % 2, nums)
A função filter()
aceita também funções lambda, além de funções convencionais.
Redução significa aplicar uma função que recebe dois parâmetros, nos dois primeiros elementos de uma sequência, aplicar novamente a função usando como parâmetros o resultado do primeiro par e o terceiro elemento, seguindo assim até o final da sequência. O resultado final da redução é apenas um elemento.
Exemplos de redução, que é implementada no Python pela função reduce()
:
In [4]:
nums = range(100)
# Soma com reduce (pode concatenar strings)
print reduce(lambda x, y: x + y, nums)
# Soma mais simples, mas só para números
print sum(nums)
A função reduce()
pode ser usada para calcular fatorial:
In [5]:
# Calcula o fatorial de n
def fat(n):
return reduce(lambda x, y: x * y, range(1, n))
print fat(6)
A partir da versão 2.6, o módulo math traz uma função que calcula fatorial chamada factorial().
Transposição é construir uma série de sequências a partir de outra série de sequências, aonde a primeira nova sequência contém o primeiro elemento de cada sequência original, a segunda nova sequência contém o segundo elemento de cada sequência original, até que alguma das sequências originais acabe.
Exemplo de transposição, que é implementada no Python pela função zip()
:
In [6]:
# Uma lista com ('a', 1), ('b', 2), ...
from string import ascii_lowercase
print zip(ascii_lowercase, range(1, 100))
# Transposta de uma matriz
matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print zip(*matriz)
A função zip()
sempre retorna uma lista de tuplas.
Em computação, List Comprehension é uma construção que equivale a uma notação matemática do tipo:
$$ S = \\{ x^{2} \forall \in \mathbb{N}, x \geq 20 \\} $$Ou seja, S é o conjunto formado por x ao quadrado para todo x no conjunto dos números naturais, se x for maior ou igual a 20.
Sintaxe:
lista = [ <expressão> for <referência> in <sequência> if <condição> ]
Exemplo:
In [7]:
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
# Eleve os ímpares ao quadrado
print [ x**2 for x in nums if x % 2 ]
In [8]:
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
# Eleve os ímpares ao quadrado
gen = ( x**2 for x in nums if x % 2 )
# Mostra os resultados
for num in gen:
print num
Outro exemplo:
In [9]:
# Uma lista de tuplas (artista, faixa):
instrumentais = [('King Crimson', 'Fracture'),
('Metallica','Call of Ktulu'),
('Yes', 'Mood for a Day'),
('Pink Floyd', 'One of This Days'),
('Rush', 'YYZ')]
# Filtra e ordena apenas as faixas de artistas anteriores a letra N
print sorted(faixa[-1] + ' / ' + faixa[0]
for faixa in instrumentais if
faixa[0].upper() < 'N')
Generator Expression usa menos recursos do que o List Comprehension equivalente, pois os itens são gerados um de cada vez, apenas quando necessário, economizando principalmente memória.
In [1]:
Out[1]: